package com.health.pay.service;
import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayConstants;
import com.github.wxpay.sdk.WXPayUtil;
import com.health.pay.config.WxPayConfig;
import com.health.pay.enums.ExceptionEnum;
import com.health.pay.enums.PayState;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Service
public class WXOrderService {

    @Autowired
    private WxPayConfig wxPayConfig;

    @Autowired
    private WXPay wxPay;

    //生成预交易链接
    public String createOrder(Long orderId, Long totalPay, String desc) {
        try {
            //数据组装
            Map<String, String> data = new HashMap<>();
            // 商品描述
            data.put("body", desc);
            // 订单号
            data.put("out_trade_no", orderId.toString());
            //金额，单位是分
            data.put("total_fee", totalPay.toString());
            //调用微信支付的终端IP  上线后 改为公网ip（服务器ip地址）
            data.put("spbill_create_ip", "127.0.0.1");
            //异步回调地址
            data.put("notify_url", wxPayConfig.getNotifyUrl());
            // 交易类型为扫码支付
            data.put("trade_type", "NATIVE");

            // 利用wxPay工具,完成下单 生成与支付连接
            Map<String, String> result = wxPay.unifiedOrder(data);

            // 判断通信和业务标示
            isSuccess(result);
            // 校验签名
            isValidSign(result);

            // 下单成功，获取支付链接
            String url = result.get("code_url");
            return url;
        } catch (Exception e) {
            log.error("[微信下单] 创建预交易订单异常失败", e);
            return null;
        }
    }

    public void isSuccess(Map<String, String> result) throws Exception{
        // 判断通信标示
        String returnCode = result.get("return_code");
        if ("FAIL".equals(returnCode)) {
            // 通信失败
            log.error("[微信下单] 微信下单通信失败,失败原因:{}", result.get("return_msg"));
            throw new Exception(ExceptionEnum.WX_PAY_ORDER_FAIL.getMsg());
        }

        // 判断业务标示
        String resultCode = result.get("result_code");
        if ("FAIL".equals(resultCode)) {
            // 通信失败
            log.error("[微信下单] 微信下单业务失败,错误码:{}, 错误原因:{}",
                    result.get("err_code"), result.get("err_code_des"));
            throw new Exception(ExceptionEnum.WX_PAY_ORDER_FAIL.getMsg());
        }
    }

    public void isValidSign(Map<String, String> result) throws Exception{
        // 校验签名
        try {
            String sign1 = WXPayUtil.generateSignature(result, wxPayConfig.getKey(), WXPayConstants.SignType.HMACSHA256);
            //String sign2 = WXPayUtil.generateSignature(result, payConfig.getKey(), WXPayConstants.SignType.MD5);

            String sign = result.get("sign");
            if (!StringUtils.equals(sign, sign1)) {
                throw new Exception(ExceptionEnum.WX_PAY_ORDER_FAIL.getMsg());
            }
        } catch (Exception e) {
            log.error("[微信支付] 校验签名失败，数据：{}", result);
            throw new Exception(ExceptionEnum.WX_PAY_ORDER_FAIL.getMsg());
        }
    }


    //处理异步回调
    public void handleNotify(Map<String, String> result) throws Exception{
        // 1 数据校验
        this.isSuccess(result);
        // 2 签名校验
        this.isValidSign(result);

        // 3 金额校验
        String totalFeeStr = result.get("total_fee");
        String tradeNo = result.get("out_trade_no");
        if(StringUtils.isEmpty(totalFeeStr) || StringUtils.isEmpty(tradeNo)){
            throw new Exception(ExceptionEnum.INVALID_ORDER_PARAM.getMsg());
        }
        Long totalFee = Long.valueOf(totalFeeStr);
        Long orderId = Long.valueOf(tradeNo);
        //根据订单id查询总金额 order=100L
        Long order=100L;
        if(totalFee != order){
            // 金额不符
            throw new Exception(ExceptionEnum.INVALID_ORDER_PARAM.getMsg());
        }

        // 4 修改订单状态
//        OrderStatus status = new OrderStatus();
//        status.setStatus(OrderStatusEnum.PAYED.value());
//        status.setOrderId(orderId);
//        status.setPaymentTime(new Date());
//        int count = orderStatusMapper.updateByPrimaryKeySelective(status);
//        if(count != 1){
//            throw new Exception(ExceptionEnum.UPDATE_ORDER_STATUS_ERROR.getMsg());
//        }

        log.info("[订单回调], 订单支付成功! 订单编号:{}", orderId);
    }


    /**
     * 查询订单状态
     * @param orderId
     * @return
     */
    public PayState queryPayState(Long orderId) {

        try {
            // 组织请求参数
            Map<String, String> data = new HashMap<>();
            // 订单号
            data.put("out_trade_no", orderId.toString());
            // 查询状态 去微信支付凭条查询订单支付状态
            Map<String, String> result = wxPay.orderQuery(data);
            // 校验状态
            isSuccess(result);
            // 校验签名
            isValidSign(result);
            // 校验金额
            String totalFeeStr = result.get("total_fee");
            String tradeNo = result.get("out_trade_no");
            if(StringUtils.isEmpty(totalFeeStr) || StringUtils.isEmpty(tradeNo)){
                throw new Exception(ExceptionEnum.INVALID_ORDER_PARAM.getMsg());
            }
            // 3.1 获取结果中的金额
            Long totalFee = Long.valueOf(totalFeeStr);
            // 3.2 获取订单金额 Long order=100L
            //Order order = orderMapper.selectByPrimaryKey(orderId);
            //money=order.getMoney();
            Long order=100L;
            if(totalFee !=order){
                // 金额不符
                throw new Exception(ExceptionEnum.INVALID_ORDER_PARAM.getMsg());
            }
            String state = result.get("trade_state");
            if("SUCCESS".equals(state)){
                // 支付成功
                // 修改订单状态
//                OrderStatus status = new OrderStatus();
//                status.setStatus(OrderStatusEnum.PAYED.value());
//                status.setOrderId(orderId);
//                status.setPaymentTime(new Date());
//                int count = orderStatusMapper.updateByPrimaryKeySelective(status);
                int count=0;
                if(count != 1){
                    throw new Exception(ExceptionEnum.UPDATE_ORDER_STATUS_ERROR.getMsg());
                }
                // 返回成功
                return PayState.SUCCESS;
            }

            if("NOTPAY".equals(state) || "USERPAYING".equals(state)){
                return PayState.NOT_PAY;
            }
            return PayState.FAIL;

        }catch (Exception e){
            return PayState.NOT_PAY;// 并不知道是否支付，再去发起请求申请一次
        }
    }
}

